#pragma once

#include "Point3d.h"
#include "ColorRGBA.h"
#include "StdAfx.h"
#include "Normal.h"


class Vertex : public Point3d
{
	public:
		Vertex( )
            : color_( 1, 1, 1 )
            , hasNormal_( false )
        {
        }

		Vertex( float x, float y, float z )
            : Point3d( x, y, z )
            , color_( 1, 1, 1 )
            , hasNormal_( false )
        {
        }

		Vertex( const ColorRGBA& color )
            : color_( color )
            , hasNormal_( false )
        {
        }

		Vertex( float x, float y, float z, const ColorRGBA& color )
            : Point3d( x, y, z )
            , color_( color )
            , hasNormal_( false )
        {
        }

		Vertex( float x, float y, float z, float R, float G, float B )
            : Point3d( x, y, z )
            , color_( R, G, B )
            , hasNormal_( false )
        {
        }

		Vertex( const Vertex& vertex )
            : Point3d( vertex.getX( ), vertex.getY( ), vertex.getZ( ) )
            , color_( vertex.getColor( ) ), hasNormal_( vertex.hasNormal( ) )
        {
			if ( vertex.hasNormal( ) )
            {
				this->normal_ = vertex.getNormal( );
            }
		}

		virtual ~Vertex(void) { }

		virtual void draw( ) const
        {			
			Point3d::draw( );
		}

		virtual const ColorRGBA& getColor( ) const
        {
			return color_;
		}

		virtual Vertex& setColor( const ColorRGBA& color)
        {
			color_ = color;
			return *this;
		}

		virtual const Vertex& setupColor( ) const
        {
			glColor3f( color_.getR( ), color_.getG( ), color_.getB( ) );
			return *this;
		}

		virtual bool operator==( const Vertex& vertex )
        {
			return Point3d::operator==( vertex ) &&
                   ( color_ == vertex.getColor( ) );
		}

		virtual bool operator!=( const Vertex& vertex )
        {
			return !( *this == vertex );
		}

		virtual bool operator<( const Vertex& vertex )
        {
			return Point3d::operator<( vertex );
		}

		virtual bool operator>( const Vertex& vertex )
        {
			return Point3d::operator>( vertex );
		}

		virtual bool operator<=( const Vertex& vertex )
        {
			return Point3d::operator<=( vertex );
		}

		virtual bool operator>=( const Vertex& vertex )
        {
			return Point3d::operator>=( vertex );
		}

		virtual bool operator<( const Vertex& vertex ) const
        {
			return Point3d::operator<( vertex );
		}

		virtual bool operator>( const Vertex& vertex ) const
        {
			return Point3d::operator>( vertex );
		}

		virtual bool operator<=( const Vertex& vertex ) const
        {
			return Point3d::operator<=( vertex );
		}

		virtual bool operator>=( const Vertex& vertex ) const
        {
			return Point3d::operator>=( vertex );
		}
/*
        virtual Vertex operator-( const Vertex& vertex )
        {
			Vertex clone( *this );
			clone.setX( clone.getX( ) - vertex.getX( ) );
			clone.setY( clone.getY( ) - vertex.getY( ) );
			clone.setZ( clone.getZ( ) - vertex.getZ( ) );
			return clone;
        }

		virtual Vertex& operator+( const Vertex& vertex )
        {
			this->setX( this->getX() + vertex.getX( ) );
			this->setY( this->getY() + vertex.getY( ) );
			this->setZ( this->getZ() + vertex.getZ( ) );
			return *this;
		}

		virtual Vertex& operator-( )
        {
			this->setX( -1 * this->getX( ) );
			this->setY( -1 * this->getY( ) );
			this->setZ( -1 * this->getZ( ) );
			return *this;
		}

		virtual Vertex operator-( const Vertex& vertex ) const
        {
			Vertex clone( *this );
			clone.setX( clone.getX( ) - vertex.getX( ) );
			clone.setY( clone.getY( ) - vertex.getY( ) );
			clone.setZ( clone.getZ( ) - vertex.getZ( ) );
			return clone;
		}

		virtual Vertex operator+( const Vertex& vertex) const
        {
			Vertex clone( *this );
			clone.setX( clone.getX( ) + vertex.getX( ) );
			clone.setY( clone.getY( ) + vertex.getY( ) );
			clone.setZ( clone.getZ( ) + vertex.getZ( ) );
			return clone;
		}

		virtual Vertex operator-( ) const
        {
			Vertex clone( *this );
			clone.setX( -1 * clone.getX( ) );
			clone.setY( -1 * clone.getY( ) );
			clone.setZ( -1 * clone.getZ( ) );
			return clone;
		}
*/
		virtual void drawNormal( ) const
        {
			normal_.draw( );
		}

		virtual Vertex& setNormal( Normal normal )
        {
            normal_ = normal;
			normal_.setOrigin( *this );
			hasNormal_ = true;
			return *this;
		}
		
		virtual const Normal& getNormal( ) const
        {
			return normal_;
		}

		virtual bool hasNormal( ) const
        {
			return hasNormal_;
		}

        virtual Vertex& setCoord( float x, float y, float z )
        {
            this->setX( x );
            this->setY( y );
            this->setZ( z );
            return *this;
        }

    private:
        ColorRGBA color_;
        bool      hasNormal_;
        Normal    normal_;
};